import axios, { AxiosRequestConfig, AxiosInstance, AxiosResponse } from 'axios'
const SUCCESS_CODE = 0
export interface IResponse<T = any> {
  content: T
  code: number
  data: T
  message: string
  server_date?: Date
  status
}

export class HTTPClient {
  private _instance: AxiosInstance

  constructor(
    config: AxiosRequestConfig = {},
    private _successCode: string | number = SUCCESS_CODE, // 请求成功的 code 值，没有 code 的时候 请传 -1
  ) {
    this._instance = axios.create({ ...config })
    this._setupCommonInterceptors()
  }

  private _setupCommonInterceptors() {
    // 请求劫持
    this._instance.interceptors.request.use(config => {
      return new Promise(resolve => {
        const requestConfig = {
          ...config,
        }
        resolve({
          ...requestConfig,
          headers: {
            'Accept-Language': 'en-us,en;q=0.5',
            ...config.headers,
          },
        })
      })
    })
    // 响应劫持
    this._instance.interceptors.response.use(
      (response: AxiosResponse) => {
        const { data, headers } = response
        if (this._successCode === -2) {
          return response
        }
        if (data.code !== this._successCode && this._successCode !== -1) {
          return Promise.reject(response)
        }
        const { date } = headers
        if (isNaN(new Date(date).getTime())) {
          return {
            ...response.data,
          }
        }
        return {
          ...response.data,
        }
      },
      err => {
        err.response?.message &&
          showToast({
            message: err.response.message || '',
          })
        return Promise.reject(err)
      },
    )
  }

  request<T = any, R extends IResponse<T> = IResponse<T>>(config: AxiosRequestConfig) {
    return this._instance.request<T, R>(config)
  }

  get<T = any, R extends IResponse<T> = IResponse<T>>(url: string, config?: AxiosRequestConfig) {
    return this._instance.get<T, R>(url, config)
  }

  head<T = any, R extends IResponse<T> = IResponse<T>>(url: string, config?: AxiosRequestConfig) {
    return this._instance.head<T, R>(url, config)
  }

  delete<T = any, R extends IResponse<T> = IResponse<T>>(url: string, config?: AxiosRequestConfig) {
    return this._instance.delete<T, R>(url, config)
  }

  post<T = any, R extends IResponse<T> = IResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig) {
    return this._instance.post<T, R>(url, data, config)
  }

  put<T = any, R extends IResponse<T> = IResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig) {
    return this._instance.put<T, R>(url, data, config)
  }

  patch<T = any, R extends IResponse<T> = IResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig) {
    return this._instance.patch<T, R>(url, data, config)
  }
}

export const http = new HTTPClient()
